home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
211_01
/
wildexpr.c
< prev
next >
Wrap
Text File
|
1980-01-01
|
11KB
|
404 lines
/* WILDEXPR.C VERS:- 01.00 DATE:- 09/26/86 TIME:- 09:37:31 PM */
/*
%CC1 $1.C -X
*/
/*
Description:
Modification of Van Nuys Toolkit - BDS C distribution version of WILDEXP:
use of <du:>, by conversion to <u/d:> form;
expansion of <d?:> and <?/d:>;
all output given uu/d: prefix, even files in current drive/user area;
restructuring of much of the code.
Size of code: hex bytes
this version: CC1 wildcard nos & du: (d?:, ?/d:)
Van Nuys: C8E user numbers (u/d: form only)
BDS C v1.50a: A8E no user numbers (d: form only)
(Inclusion of wildcard user numbers costs a little but not much.)
(The size of the du_ud() function is not included in the value cited for the
memory requirement for this version)
The number of !names allowed is 40 (= 2 !d?: + 8 !du:).
NOTE:
There must be a <du:> --> <u/d:> conversion function = du_ud().
If the conversion is required only for WILDCARD, then it is sufficient
to compile and link the du_ud function given at the end of this file.
A more general approach is to modify DEFF.CRL and DEFF2.CRL,
by adding the functions of STDLIB3R to DEFF.CRL, and
by patching the functions of DEFF2.CRL, as described in STDLIB3R.
If this is done, then all file opening, creation etc operations accept the
<du:> form.
By J.A. Rupley, Tucson, Arizona
Coded for BDS C compiler, version 1.50a
*/
/* page eject */
/*********************************************************************
* WILDEXP *
*********************************************************************/
/*
WILDEXP.C v2.0 12/26/83
BDS C Command-line Wild-card expansion utility
Revised by JA Rupley -- to include expansion of ?/ = d?:, and
conversion of du: -> u/d:
Revised by Gene Mallory
Written by Leor Zolman
Lets ambiguous file names appear on the command line to C programs,
automatically expanding the parameter list to contain all files that
fit the afn's. Returns ERROR if something went wrong; usually, this
is due to MAXITEMS being set too low; the "MAXITEMS" defined constant
sets the maximum number of matches that WILDEXP can handle. If you
need to be able to process directories with more entries than this,
be sure to modify MAXITEMS to be bigger than the largest expected
directory size.
An afn preceded by a "!" causes all names matching the given afn to
be EXCLUDED from the resulting expansion list. Thus, to yield a
command line containing all files except "COM" files, you'd say:
A>progname !*.com <cr>
Another example: to get all files on B: except .C files, say:
A>prognam b:*.* !b:*.c <cr>
When giving a "!" afn, "*" chars in the string matches to the end of
either the filename or extension, just like CP/M, but "?" chars match
ONE and ONLY ONE character in either the filename or extension.
To use WILDEXP, begin your "main" function as follows:
---------------------------------------------
main(argc,argv)
char **argv;
{
... /* local declarations */
dioinit(&argc,argv); /* if using DIO */
wildexp(&argc,&argv) /* 1st state. in prog. */
...
---------------------------------------------
and link WILDEXP.CRL in with your program. That's all there is to
it; note that "wildexp" uses the "sbrk" function to obtain storage,
so don't go playing around with memory that is outside of the
external or stack areas unless you obtain the memory through "sbrk"
or "alloc" calls.
*/
/* page eject */
#include "BDSCIO.H"
#define MAXITEMS 1333 /* max no. of items after expansion */
#define MAXUSERS 16 /* max user number in expansion of ?/ */
#define NEED_DU_UD FALSE /* set true if du_ud() not in DEFF.CRL */
#define SEARCH_FIRST 17 /* BDOS calls */
#define SEARCH_NEXT 18
#define GET_DRIVE 25
#define GET_USER 32
#define SET_DISK 14
#define SET_USER 32
#define SET_DMA 26
wildexp(argcptr, argvptr)
int *argcptr; /* pointer to argc */
char ***argvptr; /* pointer to argv */
{
int newargc; /* new argc */
char **newargv; /* new argv */
char **oldargv; /* old argv */
int oldargc; /* old argc */
int expargc; /* expansion of ?/ and d? */
char **expargv;
char fcb[36]; /* fcb used for search for first/next calls */
char dmapos; /* value returned by search calls */
char first_time; /* used in search routine */
char tmpfn[20]; /* temporary file name */
char *p_tmp; /* temporary pointer */
char *p_exp; /* another temporary pointer */
char *notfns[40]; /* list of !<afn> entries */
int notcount; /* count of entries in notfns */
char cur_drive; /* current drive number */
char cur_user; /* current user number */
char usrno; /* this file user number */
char driveno; /* this file drive number */
char buffer[128]; /* directory buffer */
int i, j, k;
cur_drive = bdos(GET_DRIVE);
cur_user = bdos(GET_USER, 0xff);
bdos(SET_DMA, buffer);
oldargv = *argvptr;
oldargc = *argcptr;
expargc = 1;
newargc = 1;
notcount = 0;
/* page eject */
/* get newargv and expargv space */
if (((newargv = sbrk(MAXITEMS * 2 + 2)) == ERROR) ||
((expargv = sbrk(MAXITEMS + 2)) == ERROR))
goto err_exit;
/* change du: to #/d: form */
/* expand all_users flag = ?/ = d?: */
/* at end of loop, handle..first name is a !name */
for (i = 1; i < oldargc; i++)
{
if (*(p_tmp = oldargv[i]) == '!')
p_tmp++;
if (du_ud(p_tmp, tmpfn))
p_tmp = tmpfn;
for (j = 0; j <= MAXUSERS; j++)
{
if ((p_exp = expargv[expargc++] = sbrk(20)) == ERROR)
goto err_exit;
if (oldargv[i][0] == '!')
*p_exp++ = '!';
if ((*p_tmp == '?') && (*(p_tmp + 1) == '/'))
{
*p_exp++ = j / 10 + '0';
*p_exp++ = j % 10 + '0';
strcpy(p_exp, (p_tmp + 1));
}
else
{
strcpy(p_exp, p_tmp);
break;
}
}
if (oldargv[1][0] == '!')
{
fsplit(&expargv[1][1], tmpfn, &usrno, &driveno,
cur_drive, cur_user);
strcpy(&tmpfn[5], "*.*");
oldargv[1] = tmpfn;
if (expargc > 2)
*++oldargv[1] = '?';
i--;
}
}
oldargv = expargv;
oldargc = expargc;
/* if not_flag on oldargv then add to not list .... */
/* else get directory files that match wildcard oldargv */
for (i = 1; i < oldargc; i++)
{
if (oldargv[i][0] == '!')
notfns[notcount++] = &oldargv[i][1];
else
{
p_tmp = fsplit(oldargv[i], tmpfn, &usrno, &driveno,
cur_drive, cur_user);
setfcb(fcb, p_tmp);
bdos(SET_DISK, driveno);
bdos(SET_USER, usrno);
first_time = TRUE;
while (1)
{
if ((dmapos = bdos((first_time ? SEARCH_FIRST
: SEARCH_NEXT), fcb)) == 255)
break;
first_time = FALSE;
if (((newargv[newargc] = sbrk(20)) == ERROR) ||
(newargc >= MAXITEMS))
goto err_exit;
makename(newargv[newargc++], tmpfn,
(buffer + dmapos * 32));
}
}
}
/* restore current drive and user */
bdos(SET_DISK, cur_drive);
bdos(SET_USER, cur_user);
/* Now eliminate all the NOT names */
for (i = 0; i < notcount; i++)
{
p_tmp = fsplit(notfns[i], tmpfn, &usrno, &driveno,
cur_drive, cur_user);
strcpy(&tmpfn[5], p_tmp);
for (j = 1; j < newargc; j++)
while (match(tmpfn, newargv[j]))
{
if (j == --newargc)
break;
for (k = j; k < newargc; k++)
newargv[k] = newargv[k + 1];
}
}
/* Replace argc and argv with new values....and exit*/
*argcptr = newargc;
*argvptr = newargv;
return 0;
err_exit :
exit(puts("WILDEXP: Out of RAM space"));
}
/* page eject */
void makename(dest, tmpfn, source)
char *dest, *tmpfn, *source;
{
int i;
/* user and drive */
while (*tmpfn)
*dest++ = *tmpfn++;
/* file name and type */
for (i = 1; i < 12; i++)
{
if ((source[i] &= 0x7f) == ' ')
continue;
if (i == 9)
*dest++ = '.';
*dest++ = source[i];
}
*dest = '\0';
}
int match(f1ptr, f2ptr)
char *f1ptr, *f2ptr;
{
char c;